package com.qmscy.sparrow.common.filter;

import com.qmscy.sparrow.common.constant.Constant;
import com.qmscy.sparrow.config.properties.JwtProperties;
import com.qmscy.sparrow.domain.User;
import com.qmscy.sparrow.plugin.jwt.TokenGenerator;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @Author: wangxiaonan
 * @Date: 2019/1/7
 **/
public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter {

    private static final Logger logger = LoggerFactory.getLogger(JWTLoginFilter.class);

    private AuthenticationManager authenticationManager;

    private JwtProperties jwtProperties;

    public JWTLoginFilter(AuthenticationManager authenticationManager, JwtProperties jwtProperties) {
        this.authenticationManager = authenticationManager;
        this.jwtProperties = jwtProperties;
//        super.setFilterProcessesUrl("/login");
    }

    /**
     * 登录时调用
     */
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
            throws AuthenticationException {
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }
        String username = obtainUsername(request);
        String password = obtainPassword(request);

        if (username == null) {
            username = "";
        }

        if (password == null) {
            password = "";
        }

        username = username.trim();

        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                username, password);

        // Allow subclasses to set the "details" property
        setDetails(request, authenticationToken);
        return this.authenticationManager.authenticate(authenticationToken);
    }

    /**
     * 登录成功后调用，设置token到header
     */
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
            Authentication auth) throws IOException, ServletException {
        // sign token
        User user = (User) auth.getPrincipal();
        String token = TokenGenerator
                .sign(user.getUsername(), user.isAdmin(), jwtProperties.getExpire(), jwtProperties.getSecret());
        // set header
        response.setHeader(Constant.RESPONSE_HEADER_AUTHORIZATION,
                String.format("%s %s", jwtProperties.getHeader(), token));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
            AuthenticationException failed) throws IOException, ServletException {
        super.unsuccessfulAuthentication(request, response, failed);
    }
}
